﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Facebook
{
    /// <summary>
    /// Class containing all you need to login in and set up a session is in this class
    /// </summary>
    internal class Login
    {
        /// <summary>
        /// Create an Auth Token, login to facebook and set up a session for further API calls
        ///  http://wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application
        /// </summary>
        internal static Facebook.auth.getSession LoginAndGetSession()
        {
            string query = LoginToFacebook();

            List<string> queryList = new List<string>(query.Split('&'));

            var sessionInfo = queryList.Where(i => i.StartsWith("session=")).FirstOrDefault();
            if (sessionInfo != null)
                return GetSession(sessionInfo.Substring(8));

            throw new Exception("Error: facebook login failure");
        }

        /// <summary>
        /// Create an Auth Token for facebook
        /// </summary>
        private static string CreateAuthToken()
        {
            // Create a token to use for the facebook session
            var parameters = new SortedDictionary<string, string>();  // Facebook parameter list (key value pair) that (needs to be sorted in order to get the MD5 hash correct - see Facebook.Security
            parameters.Add("method", "facebook.auth.createToken"); // http://wiki.developers.facebook.com/index.php/Auth.createToken
            string jsonResult = Facebook.Web.SendCallToFacebook(parameters);
            return JSON.Helper.StripSingleResult(jsonResult); // Return the Auth Token
        }

        /// <summary> 
        /// Login to facebook - needs to be done via the facebook web front end  
        /// </summary>
        private static string LoginToFacebook()
        {
            // Call the web form to do the facebook login - I couldnt find an easy work-around for a silent login :(
            var facebookLoginForm = new Facebook.Windows.Login(Facebook.Login.GetFacebookLoginPage());
            facebookLoginForm.ShowDialog();
            if (facebookLoginForm.AuthenticatedSuccessfully)
                return facebookLoginForm.CurrentPageSourceQuery;
            else
                throw new Exception("Error: facebook login failure");  // If not logged in, we can go no further                

        }

        /// <summary>
        /// Create the facebook API session object from result from login page
        /// </summary>
        private static Facebook.auth.getSession GetSession(string jsonResult)
        {
            return (JSON.Helper.Deserialize<Facebook.auth.getSession>(jsonResult));
        }

        /// <summary>
        /// Generate a url for login to facebook - this needs to be done against the facebook front end (for security reasons they say).
        /// </summary>
        /// <param name="auth_token"></param>
        /// <returns></returns>
        private static string GetFacebookLoginPage()
        {
            return String.Format(WEI_Share.Properties.Resources.FacebookLoginUrl, WEI_Share.Properties.Resources.FacebookApiKey, WEI_Share.Properties.Resources.FacebookNextLoginParameter, WEI_Share.Properties.Resources.FacebookCancelLoginParameter);
        }
    }
}
